package com.siwei.infoextract.wrapper.trainer;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;

public class CNTrainer {
	
	// This is a little tricky, we will find a better way later
	//
	public static String subCommand = null;
	public static synchronized void setSubCommand(String command) {
		subCommand = command;
	}
	public static synchronized String getSubCommand() {
		return subCommand;
	}
	
	private String trainExe;
	private String attribFile;
	private String exsFile;
	private String ruleFile;

	public CNTrainer(String trainExe, String attribFile, String exsFile, String ruleFile) {
		File file = new File(trainExe);
		if (!file.exists()) {
			throw new IllegalArgumentException("Train exe doesn't exist");
		}
		file = new File(attribFile);
		if (!file.exists()) {
			throw new IllegalArgumentException("Attribute file doesn't exist");
		}
		file = new File(exsFile);
		if (!file.exists()) {
			throw new IllegalArgumentException("Example file doesn't exist");
		}

		this.trainExe = trainExe;
		this.attribFile = attribFile;
		this.exsFile = exsFile;
		this.ruleFile = ruleFile;
	}
	
	public void train() throws IOException, InterruptedException {
		File file = new File(this.ruleFile);
		if (file.exists()) {
			file.delete();
		}

		Process process = Runtime.getRuntime().exec(trainExe);

		final InputStream inputStream  = process.getInputStream(); 
		final BufferedReader r = new BufferedReader(new InputStreamReader(inputStream)); 
		Thread out = new Thread() {
			public void run() {
				try {
					int c;
					while ((c = r.read()) != -1) {
						// just read the buffer to clear the buffer in order to unblock the process
						System.out.print((char)c);
					}
				} catch (Exception e) {
				}
			}
		};

		final OutputStream outputStream = process.getOutputStream();
		Thread in = new Thread()
		{
			public void run() 
			{
				try {
					while (true)
					{
						if (getSubCommand() != null) {
							outputStream.write((getSubCommand() + "\n").getBytes()); 
							outputStream.flush();
							setSubCommand(null);
						}
						Thread.sleep(500);
					}
				}
				catch (Exception e) 
				{
				}
			}
		};
		out.start();
		in.start();

		try {
			String[] commandSequence = {
					"r",
					"a",
					this.attribFile,
					"r",
					"e",
					this.exsFile,
					"i",
					"w",
					this.ruleFile,
					"q"
			};
	
			for (int i = 0; i < commandSequence.length; i++) {
				while(CNTrainer.getSubCommand() != null) {
					Thread.sleep(50);
				}
				CNTrainer.setSubCommand(commandSequence[i]);
			}
			Thread.sleep(2000);
		} finally {
			in.interrupt();
			out.interrupt();
			process.destroy();
		}
	}
	
	public static void main(String[] args) throws Exception {
		CNTrainer trainer = new CNTrainer(
				"F:/work/FromGuiRui/docs/cn2/cn.exe",
				"F:/test/phone.att",
				"F:/test/phone.exs",
				"F:/test/phone.rul");
		trainer.train();
	}
}
